﻿using System;
using System.Collections.Generic;
using System.Linq;
using LiveWebServiceBase.AOPLogWriter;
using LiveWebServiceBase.ServiceUserSettings;
using System.Security.Permissions;

namespace LiveWebServiceBase.ServiceUser
{
    public enum ServiceUserType
    {
        Unknown,
        ServiceUser,
        ServiceAdministrator
    }

    public class User
    {
        private string _UserName;
        private UserSettings usItem;

        public string UserName
        {
            get
            {
                return _UserName;
            }
        }
        public List<Organization> lstOrganizations;
        public ServiceUserType UserType
        {
            get
            {
                if (Settings.UserInfo.IsAdminUser(_UserName))
                    return ServiceUserType.ServiceAdministrator;
                else if (Settings.UserInfo.IsServiceUser(_UserName))
                    return ServiceUserType.ServiceUser;
                else
                    return ServiceUserType.Unknown;
            }
        }

        public User() { }
        public User(string UserName)
        {
            if (string.IsNullOrWhiteSpace(UserName)) throw new Exception("Constructor of 'User' class can not initialized by Null or white space.");
            _UserName = UserName;

            usItem = new UserSettings(_UserName);

            lstOrganizations = usItem.GetOrganizations();

            lstOrganizations.ForEach(organization =>
            {
                organization.lstSiteIDs = usItem.GetSiteIDs(organization.orgname);

                organization.lstSiteIDs.ForEach(siteid =>
                    {
                        siteid.lstAccounts = usItem.GetAccounts(siteid.value);

                        siteid.lstAccounts.ForEach(account =>
                            {
                                account.lstDomains = usItem.GetDomains(account);
                            });
                    });
            });

        }

        private string ValidateLiveID(string LiveID)
        {
            string DomainName = LiveID.Split('@')[1].ToLower();
            ValidateDomainName(DomainName);

            return DomainName;
        }

        private void ValidateDomainName(string DomainName)
        {
            if (!this.GetDomains().Contains(DomainName.ToLower()))
                throw new Exception(string.Format("Can't find domain '{0}' for '{1}' in XML settings file.", DomainName, _UserName));
        }

        public List<string> GetDomains()
        {
            List<string> result = new List<string>();

            lstOrganizations.ForEach(organization =>
                {
                    result.AddRange(organization.GetDomains());
                });

            return result;
        }

        public Organization GetOrganizationByDomainName(string DomainName)
        {
            ValidateDomainName(DomainName);
            return lstOrganizations.SingleOrDefault(O => O.GetDomains().Contains(DomainName.ToLower()));
        }

        public Organization GetOrganizationByLiveID(string LiveID)
        {
            string DomainName = ValidateLiveID(LiveID);
            return lstOrganizations.SingleOrDefault(O => O.GetDomains().Contains(DomainName.ToLower()));
        }

        public SiteID GetSiteIDByLiveID(string LiveID)
        {
            string DomainName = ValidateLiveID(LiveID);
            return lstOrganizations.Select(O => O.lstSiteIDs.SingleOrDefault(S => S.GetDomains().Contains(DomainName))).FirstOrDefault();
        }

        public Account GetAccountByLiveID(string LiveID)
        {
            string DomainName = ValidateLiveID(LiveID);
            return GetAccountByDomain(DomainName);
        }

        public Account GetAccountByDomain(string DomainName)
        {
            ValidateDomainName(DomainName);
            return lstOrganizations.Select(O => O.lstSiteIDs.SingleOrDefault(S => S.GetDomains().Contains(DomainName)).lstAccounts.SingleOrDefault(A => A.lstDomains.Contains(DomainName))).SingleOrDefault();
        }
    }
}
